<template>
	<view class="topic-box">
		<!-- 顶部导航栏 -->
		<zero-custom-bar :singleIcon="true" :singleIconType="'back'" :title="title" v-slot:default>
			<!-- 答题/背题模式切换 -->
			<view class="topic-nav" v-if="type != 2">
				<text @click="modeSwitch(1)" :class="{ 'on': question_mode == 1 }">答题模式</text>
				<text @click="modeSwitch(2)" :class="{ 'on': question_mode == 2 }">背题模式</text>
			</view>
			<text v-if="type == 2">{{ title }}</text>
		</zero-custom-bar>

		<view class="topic-main">
			<!-- 题目轮播器 - 只有在swiperList有有效数据时才渲染 -->
			<swiper v-if="swiperList && swiperList.length > 0 && swiperList.some(item => item && item.questions)" 
				class="swiper" :duration="duration" :style="{ 'height': swiperH }"
				:current="current" @animationfinish="swiperChange">
				<swiper-item class='swiper-item' v-for="(items, index) in swiperList" :key="`swiper-${index}-${items?.id || 'empty'}`">
					<view class="swiper-topic" v-if="items && items.questions">
						<scroll-view scroll-y="true" :style="{ 'height': swiperH }" class="item-box">
							<view style="padding-bottom: 240rpx;">
								<view style="padding-top: 20rpx;" v-for="(item, inx) in items.questions" :key="`question-${item.id}-${item.userAnswer || 'no-answer'}`">
                                <question-item 
                                        :data="{ ...item, img: items.img }" 
                                        :question_mode="question_mode"
                                        :display="display" 
                                        :type="item.type"
                                        :index="getGlobalQuestionIndex(index, inx)"
                                        :showAnswer="shouldShowAnswer"
                                        :showUserAnswer="shouldShowUserAnswer" 
                                        :questionIndex="inx" 
                                        :mode="Number(mode)" 
                                        @radioClick="handleAnswer"
                                        @previewImage="previewImage" />
								</view>
							</view>
						</scroll-view>
					</view>
				</swiper-item>
			</swiper>
			<!-- 导航按钮 -->
			<view @click="prevQuestion" v-if="currItemNo > 1" class="btn" style="left: 30rpx;">上一题</view>
			<view v-if="type != 5" @click="submitPaper" class="btn-submit">
				{{type == 2 ? '提交试卷' : '查看练习结果'}}
				<text class="iconfont icon-erjiyemianjiantou01"></text>
			</view>
			<view @click="nextQuestion" v-if="currItemNo < query.total" class="btn"
				:class="{ 'btn-on': currItemNo < query.total }" style="right: 30rpx;">下一题</view>
			<!-- 底部工具栏 -->
			<view class="bottom-box">
				<view class="bottom-box-left">
					<!-- 答题卡 -->
					<view class="bottom-box-tag" @click="topicClick">
						<text style="font-size: 26rpx; padding-right: 5rpx;">答题卡</text>
						<view class="iconfont icon-datiqia1" style="color: #2386FF;font-size: 42rpx;"></view>
					</view>
					<!-- 正确题数 -->
					<view class="bottom-box-tag">
						<view class="iconfont icon-zhengque1"></view>
						<text v-if="type == 2">{{ correctCount + wrongCount }}</text>
						<text v-else>{{ Math.round(correctCount) }}</text>
					</view>
					<!-- 错误题数 -->
					<view v-if="type != 2" class="bottom-box-tag">
						<view class="iconfont icon-cuowu"></view>
						<text>{{wrongCount}}</text>
					</view>
					<!-- 未答题数 -->
					<view class="bottom-box-tag">
						<view class="iconfont icon--lx-unanswer" style="color: #878787;"></view>
						<text>{{ unansweredCount }}</text>
					</view>
					<!-- 当前进度 -->
					<text class="count">{{ currItemNo }}/{{ query.total}}</text>
				</view>
				<!-- 收藏按钮 -->
				<view class="bottom-box-right" :class="{ 'on': list[currItemNo - 1]?.collect }" @click="collectClick">
					<view class="iconfont icon-hanhan-01-01"></view>
					<text>收藏</text>
				</view>
			</view>
		</view>

		<!-- 答题卡弹窗 -->
		<uni-popup ref="popup" type="bottom" :background-color="'#fff'" :borderRadius="'20rpx 20rpx 0 0'">
			<view class="list-topic">
				<!-- 弹窗头部 -->
				<view class="list-top">
					<view class="list-top-txt">
						<text class="list-top-txt-title">答题进度</text>
						<text style="color: #000000FF;">{{ correctCount + wrongCount }}</text>
						<text style="color: #949494FF;">/{{ query.total }}</text>
					</view>
					<view @click="closeList" class="iconfont icon-cuowuguanbiquxiao"></view>
				</view>

				<!-- 答题统计 -->
				<view class="list-record">
					<view class="list-record-icon">
						<template v-if="type == 2">
							<view style="color: #2386ffFF;" class="iconfont icon-zhengque"></view>
							<text>已答 {{ correctCount + wrongCount }} </text>
						</template>
						<template v-else>
							<view style="color: #2386ffFF;" class="iconfont icon-zhengque1"></view>
							<text>正确 {{ correctCount }} </text>
							<view style="color: #e23321FF;" class="iconfont icon-cuowu1"></view>
							<text>错误 {{ wrongCount }}</text>
						</template>
						<view style="color: #878787;" class="iconfont icon--lx-unanswer"></view>
						<text>未答 {{ unansweredCount }}</text>
					</view>
					<view class="list-record-clear" @click="clearRecord">{{ type == 3 ? '清空错题记录' : '清空做题记录' }}</view>
				</view>

				<!-- 题目列表 -->
				<scroll-view :scroll-top="scrollTop" scroll-y class="list-item-box">
					<view class="list-item">
						<view class="list-item-top" :class="{
							'multi': list[index]?.questions?.length > 1,
							['item-box-' + index]: true,
							'current': index === (currItemNo - 1),
							'placeholder': !list[index] || list[index] === null
						}" v-for="(item, index) in query.total" :key="index" @click="selectItem(index)">
							<text class="list-item-box-title" :class="{ ...getQuestionStatus(index) }">{{ index + 1 }}</text>
							<view class="list-item-box-item" v-if="list[index]?.questions?.length > 1">
								<text class="list-item-box-item-text"
									:class="{ ...getSubQuestionStatus(index, subIndex) }"
									v-for="(question, subIndex) in list[index].questions" :key="subIndex">
									{{ subIndex + 1 }}
								</text>
							</view>
						</view>
					</view>
				</scroll-view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
import { getTopicList, addUserTopic, paperCollect, delPaperCollect, getUserItemAnswerList, getPaperCollectList, getUserPaper, addUserPaper, getSubPaper, addSubPaper, getUserPaperDetail, getSubPaperDetail, clearTopicAnswer, getTopicErrorTop, delTopicAnswer } from '@/http/question.js'
import QuestionItem from '@/components/question-item.vue'
import { initSwiper, leapToItem, changeSwiperItem, defaultParams } from '@/utils/kevy-enhanced-swiper-1.0.js';

export default {
	components: {
		QuestionItem
	},
	// question type 3 判断  1单选  2 多选 
	data() {
        // 使用defaultParams的默认值
        var { duration } = defaultParams;
		
		return {
			list: [], // 源数据
			originalList: [], // 原始数据（未经过transformData处理）
			// 使用kevy-enhanced-swiper所需的属性
			swiperList: [], // swiper显示的数据（最多3个）
			current: 0, // 当前在swiperList中的位置（0,1,2）
			currItemNo: 1, // 当前实际的项目编号（从1开始）
			duration: duration, // 使用defaultParams中的默认时长
			
			question_mode: 1, // 1 答题模式 2背题模式
			swiperH: '1300rpx',
			title: '',
			query: {
				opc: '',
				pageNum: 1,
				pageSize: 100, // 默认100条
				total: 0
			},
			startTime: 0,
			scrollTop: null,
			type: '', // 类型 1 顺序练习 2 模拟考试 3 错题练习 4 收藏练习 5 查看试卷
			mode: 1, // 题目模式 1 单题目 2 科目三
			id: '',
			paper: {},
			display: false,
			countdown: {
				hours: 2,
				minutes: 0,
				seconds: 0,
				timer: null
			},
			date: '',
			topicCode: '',
			name: '',
            isSubmittingAnswer: false, // 防止答题过程中自动跳转到未做题
			isJumpLoading: false, // 题目跳转loading状态
			isPageLoading: false, // 分页加载loading状态
			progressKey: '', // 进度存储的key，用于区分不同的练习
			enableProgressTracking: false, // 是否启用进度跟踪
			loadMoreDebounceTimer: null, // 加载更多的防抖定时器
			isResetting: false, // 是否正在重置题目
			isPreloading: false, // 是否正在预加载（用于禁用checkLoadMore）
			loadingPages: new Set(), // 正在加载的页面集合，防止重复加载
			isProgrammaticSwipe: false, // 是否是程序主动触发的swiper切换（非用户手动滑动）
			isSwiperAnimating: false, // swiper是否正在执行切换动画，防止连续点击累积
			courseId:null // 课程id
		}
	},
	computed: {
		// 计算正确题目数量
		correctCount() {
			return this.list.reduce((total, item) => {
				// 跳过null占位符
				if (!item || !item.questions || !item.questions.length) return total

				// 对于图片+多个问题的结构，只有当所有子问题都答对了才算正确
				const allQuestionsAnswered = item.questions.every(question =>
					question.userAnswer !== undefined && question.userAnswer !== ''
				)
				const allQuestionsCorrect = item.questions.every(question =>
					question.userAnswer !== undefined &&
					question.userAnswer !== '' &&
					question.answer === question.userAnswer
				)

				// 只有当所有子问题都答了且都答对了，才算一个正确题目
				return total + (allQuestionsAnswered && allQuestionsCorrect ? 1 : 0)
			}, 0)
		},
		// 计算错误题目数量 
		wrongCount() {
			return this.list.reduce((total, item) => {
				// 跳过null占位符
				if (!item || !item.questions || !item.questions.length) return total

				// 对于图片+多个问题的结构，如果有任何子问题答错了就算错误
				const hasWrongAnswer = item.questions.some(question =>
					question.userAnswer !== undefined &&
					question.userAnswer !== '' &&
					question.answer !== question.userAnswer
				)

				// 如果有任何子问题答错了，就算一个错误题目
				return total + (hasWrongAnswer ? 1 : 0)
			}, 0)
		},
		// 计算未答题数量
		unansweredCount() {
			// 计算实际加载的题目数（排除null占位符）
			const actualLoadedQuestions = this.list.filter(item => item !== null && item !== undefined).length

			// 未答题数量 = 总题目数 - 已答题数量（正确 + 错误）
			return this.query.total - (this.correctCount + this.wrongCount)
		},

		// 控制答案显示逻辑
		shouldShowAnswer() {
			// 所有模式都显示答案，但需要根据答题状态来控制
			const currentQuestion = this.list[this.currItemNo - 1]
			if (currentQuestion && currentQuestion.questions && currentQuestion.questions.length > 0) {
				// 检查是否有任何子问题已提交
				return currentQuestion.questions.some(q => q.isSubmitted)
			}
			return false
		},

		// 控制是否显示用户选择的答案
		shouldShowUserAnswer() {
			// 所有模式都显示用户选择的答案
			return true
		}
	},

	onLoad(options) {
		if (options.display) {
			this.display = true
		}
		if (options.date) {
			this.date = options.date
		}
		if (options.mode) {
			this.mode = options.mode
		}
		if (options.id) {
			this.id = options.id
		}
		if (options.topicCode) {
			this.topicCode = options.topicCode
		}
		if (options.name) {
			this.name = options.name
		}
		if (options.title) {
			this.title = options.title
		}
		if (options.courseId) {
			this.courseId = options.courseId
		}

		
		this.query.opc = options.opc
		this.type = options.type

		// 初始化进度跟踪（仅理论模式顺序练习启用）
		this.initProgressTracking()
		
		uni.showLoading({
			title: '加载中题目中...',
			mask: true
		})
		this.startTime = new Date().getTime()
		this.loadData()

	},



	methods: {
		/**
		 * 初始化进度跟踪
		 * 仅在理论模式顺序练习时启用
		 */
		initProgressTracking() {
			// 只有理论模式(mode == 1)且顺序练习(type == 1)才启用进度跟踪
			if (this.mode == 1 && this.type == 1) {
				this.enableProgressTracking = true
				// 生成进度存储key，包含opc和topicCode以区分不同的练习
				this.progressKey = `progress_${this.query.opc}_${this.topicCode || 'default'}`
			}
		},

		/**
		 * 预加载目标页面的前后页
		 * 智能加载策略：先加载后面一页，再按倒序加载前面所有页面（优先向后浏览）
		 * @param {number} targetPageNum - 目标页码
		 */
		async preloadAdjacentPages(targetPageNum) {
			console.log(`开始预加载第${targetPageNum}页的前后页...`)
			
			// 计算总页数
			const totalPages = Math.ceil(this.query.total / this.query.pageSize)
			
			// 1. 先加载后面一页（如果存在且不是目标页）- 优先向后浏览
			const nextPage = targetPageNum + 1
			if (nextPage <= totalPages && nextPage !== targetPageNum) {
				// 检查后面一页是否已加载
				const nextPageStartIndex = (nextPage - 1) * this.query.pageSize
				const nextPageEndIndex = Math.min(nextPage * this.query.pageSize, this.query.total)
				const hasNextPageData = this.list.slice(nextPageStartIndex, nextPageEndIndex).some(item => item !== null && item !== undefined && item.questions)
				
				if (!hasNextPageData) {
					try {
						console.log(`开始加载后面一页（第${nextPage}页）...`)
						await this.loadPageData(nextPage) // loadPageData 内部会自动更新 swiperList
						console.log(`后面一页（第${nextPage}页）加载完成`)
					} catch (error) {
						console.error(`加载第${nextPage}页失败:`, error)
					}
				} else {
					console.log(`第${nextPage}页已有数据，跳过加载`)
				}
			}
			
			// 2. 再按倒序加载前面所有页面（从目标页前一页到第1页）
			if (targetPageNum > 1) {
				console.log(`开始加载前面所有页面（第${targetPageNum - 1}页 到 第1页）...`)
				for (let pageNum = targetPageNum - 1; pageNum >= 1; pageNum--) {
					// 检查该页是否已加载
					const pageStartIndex = (pageNum - 1) * this.query.pageSize
					const pageEndIndex = Math.min(pageNum * this.query.pageSize, this.query.total)
					const hasPageData = this.list.slice(pageStartIndex, pageEndIndex).some(item => item !== null && item !== undefined && item.questions)
					
					if (!hasPageData) {
						try {
							console.log(`开始加载第${pageNum}页...`)
							await this.loadPageData(pageNum) // loadPageData 内部会自动更新 swiperList
							console.log(`第${pageNum}页加载完成`)
						} catch (error) {
							console.error(`加载第${pageNum}页失败:`, error)
						}
					} else {
						console.log(`第${pageNum}页已有数据，跳过加载`)
					}
				}
			}
			
			console.log(`预加载完成！加载顺序: 第${targetPageNum}页 → 第${nextPage}页 → 第${targetPageNum - 1}到第1页`)
		},

	/**
	 * 检查并确保题目数据已加载
	 * @param {number} questionNo - 题目编号（从1开始）
	 * @param {string} direction - 方向提示（'下一题'、'上一题'或'目标题目'）
	 * @returns {Promise<boolean>} 返回true表示数据已就绪，false表示需要等待
	 */
	async checkAndLoadQuestion(questionNo, direction = '题目') {
		console.log(`[checkAndLoadQuestion] 检查第${questionNo}题, 方向: ${direction}`)
		
		const targetIndex = questionNo - 1 // 转换为数组索引
		
		// 检查索引是否有效
		if (targetIndex < 0 || targetIndex >= this.query.total) {
			console.log(`[checkAndLoadQuestion] 索引无效: ${targetIndex}, total: ${this.query.total}`)
			return false
		}
		
		const targetItem = this.list[targetIndex]
		
		// 如果数据已加载，直接返回true
		if (targetItem && targetItem !== null && targetItem.questions) {
			console.log(`[checkAndLoadQuestion] 第${questionNo}题数据已加载，可以跳转`)
			return true
		}
		
		console.log(`[checkAndLoadQuestion] 第${questionNo}题数据未加载，开始加载...`)
		
		// 数据未加载，提示用户
		uni.showToast({
			title: `${direction}数据加载中，请稍候...`,
			icon: 'none',
			duration: 2000
		})
		
		// 尝试加载目标页数据
		const targetPageNum = Math.floor(targetIndex / this.query.pageSize) + 1
		
		try {
			await this.loadPageData(targetPageNum)
			
			// 验证数据是否加载成功
			const loadedItem = this.list[targetIndex]
			if (loadedItem && loadedItem !== null && loadedItem.questions) {
				console.log(`[checkAndLoadQuestion] 第${questionNo}题加载成功`)
				uni.showToast({
					title: '加载完成',
					icon: 'success',
					duration: 1000
				})
				return true
			} else {
				console.error(`[checkAndLoadQuestion] 第${questionNo}题加载后验证失败`, loadedItem)
				throw new Error('数据加载后验证失败')
			}
		} catch (err) {
			console.error(`[checkAndLoadQuestion] 加载第${questionNo}题失败:`, err)
			uni.showToast({
				title: '加载失败，请重试',
				icon: 'none',
				duration: 2000
			})
			return false
		}
	},

	/**
	 * 保存当前进度
	 * @param {number} currentItemNo - 当前题目编号
	 */
	saveProgress(currentItemNo) {
			if (!this.enableProgressTracking) return
			
			try {
				const progressData = {
					currentItemNo: currentItemNo,
					timestamp: new Date().getTime(),
					opc: this.query.opc,
					topicCode: this.topicCode || '',
					total: this.query.total
				}
				
				uni.setStorageSync(this.progressKey, progressData)
				console.log(`进度已保存: 第${currentItemNo}题`)
			} catch (error) {
				console.error('保存进度失败:', error)
			}
		},

		/**
		 * 恢复历史进度
		 * @returns {number|null} 返回历史进度的题目编号，如果没有则返回null
		 */
		restoreProgress() {
			if (!this.enableProgressTracking) {
				console.log('进度跟踪未启用，跳过恢复')
				return null
			}
			
			try {
				const progressData = uni.getStorageSync(this.progressKey)
				if (progressData && progressData.currentItemNo) {
					console.log(`发现历史进度: 第${progressData.currentItemNo}题 (总共${progressData.total}题)`)
					console.log(`当前已加载题目数: ${this.list.length}`)
					return progressData.currentItemNo
				} else {
					console.log('未找到历史进度记录')
				}
			} catch (error) {
				console.error('恢复进度失败:', error)
			}
			return null
		},

		/**
		 * 清除进度记录
		 */
		clearProgress() {
			if (!this.enableProgressTracking) return
			
			try {
				uni.removeStorageSync(this.progressKey)
				console.log('进度记录已清除')
			} catch (error) {
				console.error('清除进度失败:', error)
			}
		},

		/**
		 * 加载题目数据
		 * 根据不同的模式和类型加载对应的题目数据
		 */
		loadData() {
			// mode 2 科目三
			if (this.mode == 2) {
				let list
				if (this.id) {
					this.title = this.type == 3 ? '科三试卷错题' : '科三试卷查看';
					console.log(this.id, '10:34:13 🚀 ~ file: questionList.vue:521 ~ ');
				getSubPaperDetail({ id: this.id }).then(res => {
					this.originalList = res.data.list // 保存原始数据
					this.list = this.transformData(res.data.list)
					this.query.total = this.list.length
					this.initSwiperData()
				})
					this.question_mode = 2
				} else {
					this.title = this.type == 1 ? '科三顺序练习' : '科三模拟考试';
					getSubPaper({
						opc: this.query.opc,
						pageSize: 100,
						pageNum: 1,
						custom: this.type == 2 ? (this.query.opc == '030302' || this.query.opc == '030301' ? 10 : 20) : 0,
						type: this.type == 1 ? 0 : 1
					}).then(res => {
						list = res.data.list.map(item => {
							return {
								...item,
								type: item.tqType,
							}
						})
						this.originalList = list // 保存原始数据
						this.list = this.transformData(list)
						this.query.total = this.list.length
						this.initSwiperData()
					})
				}
			} else {
				// mode 1 理论练习
				if (this.type == 2) {
					// 模拟考试保持答题模式，不设置背题模式
					// 设置初始标题
					this.title = '02:00:00';
					getUserPaper({
						opc: this.query.opc,
						num: 100
					}).then(res => {
						this.paper = {
							id: res.data.id,
							score: res.data.score,
							status: res.data.status,
							userId: res.data.userId,
							opc: res.data.opc,
							num: res.data.num
						}
						this.originalList = res.data.topicList // 保存原始数据
						this.list = this.transformData(res.data.topicList)
						this.query.total = this.list.length
						this.initSwiperData()
						// 数据加载完成后开始倒计时
						this.startCountdown();
					})
				}
				const { pageNum, pageSize, opc } = this.query
				if (this.type == 3) {
					this.title = '理论错题练习'
					uni.setNavigationBarTitle({
						title: this.title
					})
					
					if (this.id) {
						getUserPaperDetail({
							id: this.id
						}).then(res => {
							let errList = res.data.topicList.filter(item => item.userAnswer && item.userAnswer !== item.answer).map(item => ({
								...item,
								userAnswer: ''
							}))
                            
							this.originalList = errList // 保存原始数据
							this.list = this.transformData(errList)
							this.query.total = this.list.length
							this.initSwiperData()
						})
					} else {
						getUserItemAnswerList({
							opc,
							...(this.date ? { date: this.date } : {}),
							pageNum,
							pageSize,
							type: 0,  // 0 错 1对
						}).then(res => {
							this.originalList = res.data.list // 保存原始数据
							this.list = this.transformData(res.data.list)
							this.query.total = this.list.length
							this.initSwiperData()
						})
					}
				}
				if (this.type == 4) {
					this.title = '理论收藏题'
					getPaperCollectList({
						opc,
						pageNum,
						pageSize
					}).then(res => {
						if (res.data.list.length > 0) {
							this.originalList = res.data.list // 保存原始数据
							this.list = this.transformData(res.data.list)
							this.query.total = this.list.length
							this.initSwiperData()
						} else {
							uni.hideLoading()
							uni.showModal({
								title: '暂无收藏题',
								content: '您还没有收藏任何题目哦',
								showCancel: false,
								success: function (res) {
									uni.navigateBack()
								}
							})
						}
					})
				}
			if (this.type == 1) {
				this.title = this.name ? this.name : '理论顺序练习'
				
				// 先检查是否有缓存，决定初始加载哪一页
				let initialPageNum = pageNum
				let hasCache = false
				if (this.enableProgressTracking) {
					const progressData = uni.getStorageSync(this.progressKey)
					if (progressData && progressData.currentItemNo) {
						// 计算缓存题目所在的页码
						const cachePageNum = Math.floor((progressData.currentItemNo - 1) / this.query.pageSize) + 1
						if (cachePageNum > 1) {
							initialPageNum = cachePageNum
							hasCache = true
							console.log(`检测到缓存在第${cachePageNum}页，初始化时直接加载第${cachePageNum}页`)
						}
					}
				}
				
			// 先加载缓存所在页
			getTopicList({
				pageNum: initialPageNum,
				pageSize,
				opc,
				...(this.topicCode ? { topicCode: this.topicCode } : {})
			}).then(res => {
				this.query.total = res.data.total
				
				// 更新当前页码状态，避免后续loadNextPageSilently重复加载
				this.query.pageNum = initialPageNum
				console.log(`初始化完成，当前页码: ${this.query.pageNum}`)
		
				// 如果初始加载的不是第1页，需要用null填充前面的位置
				if (initialPageNum > 1) {
					const fillCount = (initialPageNum - 1) * pageSize
					this.originalList = Array(fillCount).fill(null).concat(res.data.list)
					this.list = Array(fillCount).fill(null).concat(this.transformData(res.data.list))
				} else {
					this.originalList = res.data.list // 保存原始数据
					this.list = this.transformData(res.data.list)
				}
				
			// 先初始化UI，让用户立即看到内容
			this.initSwiperData()
			
			// 如果有缓存，在swiper完全初始化后再后台加载前后页
			if (hasCache && initialPageNum > 1) {
				// 设置预加载标志，禁用checkLoadMore自动加载
				this.isPreloading = true
				console.log('开始预加载，暂时禁用checkLoadMore自动加载')
				
				// 使用setTimeout延迟更长时间，确保swiper完全初始化
				setTimeout(() => {
					this.preloadAdjacentPages(initialPageNum).catch(err => {
						console.error('后台预加载前后页失败:', err)
					}).finally(() => {
						// 预加载完成后，清除标志，恢复checkLoadMore
						this.isPreloading = false
						console.log('预加载完成，恢复checkLoadMore自动加载')
					})
				}, 500) // 延迟500ms，确保swiper完全稳定
			}
		})
			}
				if (this.type == 5) {
					this.title = '查看试卷'
					getUserPaperDetail({
						id: this.id
					}).then(res => {
						this.originalList = res.data.topicList // 保存原始数据
						this.list = this.transformData(res.data.topicList)
						this.query.total = this.list.length
						this.initSwiperData()
					})
				}
				if (this.type == 6) {
					this.title = '易错题'
					getTopicErrorTop({
						pageNum,
						pageSize,
						opc,
						...(this.topicCode ? { topicCode: this.topicCode } : {})
					}).then(res => {
						this.query.total = res.data.total
						this.originalList = res.data.map(item => ({
							...item,
							id: item.topicId
						})) // 保存原始数据
						this.list = this.transformData(res.data)
						this.initSwiperData()
					})
				}
			}

		},

		// 初始化Swiper数据
		async initSwiperData() {
			if (!this.list || !this.list.length) return

			// 先检查是否需要恢复历史进度
			let startPosition = 1 // 默认从第一题开始
			let needHideLoading = false // 是否需要关闭loading
			
			if (this.enableProgressTracking) {
				const historyProgress = this.restoreProgress()
				if (historyProgress && historyProgress <= this.query.total) {
					startPosition = historyProgress
					
					// 检查历史进度是否需要加载数据
					const historyIndex = historyProgress - 1
					if (!this.list[historyIndex] || this.list[historyIndex] === null) {
						const targetPageNum = Math.floor(historyIndex / this.query.pageSize) + 1
						
						console.log(`历史进度第${historyProgress}题在第${targetPageNum}页，开始按顺序加载数据...`)
						
						uni.showLoading({
							title: '恢复学习进度...',
							mask: true
						})
						
						needHideLoading = true // 标记需要关闭loading
						console.log('开始显示进度恢复loading')
						
						try {
							// 直接加载目标页面，用空数据补齐前面的位置
							await this.loadTargetPageDirectly(targetPageNum, historyIndex)
							
							// 验证数据是否正确加载
							if (!this.list[historyIndex] || this.list[historyIndex] === null || !this.list[historyIndex].questions) {
								throw new Error(`第${historyProgress}题数据加载失败`)
							}
							
							console.log(`第${historyProgress}题数据加载成功`)
						} catch (error) {
							console.error('加载历史进度数据失败:', error)
							startPosition = 1 // 加载失败时回到第一题
							// 加载失败时立即关闭loading
							uni.hideLoading()
							needHideLoading = false
						}
					} else if (historyProgress > 1) {
						// 不需要加载数据但需要跳转到历史进度，也显示loading
						uni.showLoading({
							title: '恢复学习进度...',
							mask: true
						})
						needHideLoading = true
					}
				}
			}
			
			// 直接在正确位置初始化swiper，并在UI渲染完成后关闭loading
			// 如果没有需要恢复的进度或不需要额外loading，统一关闭最初的loading
			this.initSwiperAtPosition(startPosition, needHideLoading || !this.enableProgressTracking || startPosition === 1)
		},

		/**
		 * 在指定位置初始化swiper
		 * @param {number} position - 起始位置（从1开始）
		 * @param {boolean} needHideLoading - 是否需要关闭loading
		 */
		initSwiperAtPosition(position, needHideLoading = false) {
			const idx = position - 1
			let swiperList, current
			
			// 验证目标位置的数据是否存在且完整
			if (!this.list[idx] || this.list[idx] === null || !this.list[idx].questions) {
				console.warn(`位置${position}的数据不完整，回到第一题`)
				position = 1
				idx = 0
			}
			
			if (this.list.length <= 3) {
				// 少于等于3个元素时，显示所有元素
				swiperList = this.list
				current = idx
			} else {
				// 超过3个元素时，根据位置计算显示的3个元素
				if (idx === 0) {
					// 第一个位置
					swiperList = [this.list[0], this.list[1], this.list[2]]
					current = 0
				} else if (idx === this.list.length - 1) {
					// 最后一个位置
					swiperList = [this.list[idx - 2], this.list[idx - 1], this.list[idx]]
					current = 2
				} else {
					// 中间位置
					swiperList = [this.list[idx - 1], this.list[idx], this.list[idx + 1]]
					current = 1
				}
			}
			
			// 过滤掉null值，确保swiperList中都是有效数据
			const validSwiperList = swiperList.filter(item => item !== null && item !== undefined && item.questions)
			
			if (validSwiperList.length === 0) {
				console.error('没有有效的题目数据')
				if (needHideLoading) {
					uni.hideLoading()
				}
				uni.showToast({
					title: '题目数据加载失败',
					icon: 'none'
				})
				return
			}
			
			// 如果过滤后的数据不足，调整显示逻辑
			if (validSwiperList.length !== swiperList.length) {
				console.warn('部分题目数据缺失，使用有效数据初始化')
				// 使用有效数据重新计算
				swiperList = validSwiperList
				current = 0 // 简化为第一个有效位置
			}
			
			// 设置swiper状态
			this.swiperList = [...swiperList] // 使用数组副本，确保响应式更新
			this.current = current
			this.currItemNo = position
			
			// 等待UI完全渲染完成
			this.$nextTick(() => {
				// 再等待一帧确保所有组件都渲染完成
				this.$nextTick(() => {
					// 额外等待一点时间确保swiper动画和组件渲染完成
					setTimeout(() => {
						// 关闭loading（如果需要的话）
						if (needHideLoading) {
							console.log('准备关闭进度恢复loading')
							uni.hideLoading()
							console.log('进度恢复loading已关闭')
						}
						
						// 显示恢复成功的提示（如果是从历史进度恢复的话）
						if (position > 1 && this.enableProgressTracking) {
							uni.showToast({
								title: '已恢复到上次学习进度',
								icon: 'none'
							})
						}
						
						// 关闭重置loading（如果是重置操作的话）
						if (this.isResetting) {
							uni.hideLoading()
							uni.showToast({
								title: '重置成功，已回到第一题',
								icon: 'success'
							})
							this.isResetting = false
						}
					}, 200) // 增加等待时间到200ms，确保UI完全渲染
				})
			})
		},



		/**
		 * 跳转到指定题目
		 * @param {number} questionNo - 题目编号（从1开始）
		 * @param {string} message - 提示消息
		 */
		jumpToQuestion(questionNo, message = '') {
			if (questionNo < 1 || questionNo > this.query.total) return
			
			leapToItem(this, questionNo, this.list, this.duration, () => {
				if (message) {
					uni.showToast({
						title: message,
						icon: 'none'
					})
				}
			})
		},



	/**
	 * 检查是否需要加载更多数据
	 * 当题目数量达到当前页面的70%时，开始在后台加载下一页
	 */
	async checkLoadMore() {
		// 如果正在预加载，跳过自动加载检查
		if (this.isPreloading) {
			console.log('正在预加载中，跳过checkLoadMore自动加载')
			return
		}
		
		// 如果已经在加载中或没有更多数据，直接返回
		if (this.isPageLoading || this.list.length >= this.query.total) {
			return
		}
		
		// 计算实际已加载的题目数量（排除null占位符）
		const loadedCount = this.list.filter(item => item !== null && item !== undefined && item.questions).length
		
		// 计算当前已加载题目的70%位置
		const threshold = Math.floor(loadedCount * 0.7)
		console.log(threshold, '858');
		
		// 当用户做到当前已加载题目70%时，开始在后台加载下一页
		if (this.currItemNo >= threshold && loadedCount < this.query.total) {
			// 计算下一页页码
			const nextPageNum = this.query.pageNum + 1
			const totalPages = Math.ceil(this.query.total / this.query.pageSize)
			
			// 检查下一页是否存在
			if (nextPageNum > totalPages) {
				return
			}
			
			// 检查下一页是否已加载
			const nextPageStartIndex = (nextPageNum - 1) * this.query.pageSize
			const nextPageEndIndex = Math.min(nextPageNum * this.query.pageSize, this.query.total)
			const hasNextPageData = this.list.slice(nextPageStartIndex, nextPageEndIndex).some(item => item !== null && item !== undefined && item.questions)
			
			if (hasNextPageData) {
				console.log(`下一页（第${nextPageNum}页）已加载，跳过自动加载`)
				return
			}
			
			console.log(`当前题目${this.currItemNo}已达到已加载题目70%阈值${threshold}（已加载${loadedCount}题），开始在后台加载下一页（第${nextPageNum}页）...`)
			
			// 使用防抖机制，避免频繁触发加载
			if (this.loadMoreDebounceTimer) {
				clearTimeout(this.loadMoreDebounceTimer)
			}
			
			this.loadMoreDebounceTimer = setTimeout(async () => {
				try {
					await this.loadNextPageSilently()
				} catch (error) {
					console.error('后台加载下一页失败:', error)
					// 静默失败，不影响用户体验
				}
			}, 300) // 300ms防抖延迟
		}
	},




        

		/**
		 * 计算全局题目序号（简化版本 - 直接返回题目序号）
		 * @param {number} itemIndex - swiper中的题目索引（未使用）
		 * @param {number} subIndex - 子题目索引
		 * @returns {number} 全局题目序号
		 */
		getGlobalQuestionIndex(itemIndex, subIndex) {
			// 简化逻辑：直接返回当前题目的序号
			// 因为现在每个题目只有一个子问题，所以直接返回 currItemNo - 1 + subIndex
			return this.currItemNo - 1 + subIndex
		},

		/**
		 * 提交科目三试卷
		 * @param {Object} params - 试卷参数
		 */
		async submitSubPaper(params) {
			const examScore = uni.getStorageSync('examScore')
			console.log(examScore, '10:26:10 🚀 ~ file: questionList.vue:1005 ~ ');
			params.score = examScore.correct
			try {
				const res = await addSubPaper(params)
				uni.showToast({
					title: '提交成功',
					icon: 'success',
					success: () => {
						uni.redirectTo({
							url: `/pages/question/score?type=${this.type}&id=${res.data.id}&opc=${this.query.opc}&mode=2`
						})
					}
				})
			} catch (err) {
				console.error('提交科目三试卷失败:', err)
				uni.showToast({
					title: '提交失败，请重试',
					icon: 'none'
				})
			}
		},

		/**
		 * 提交理论试卷
		 * @param {Object} params - 试卷参数
		 */
		async submitUserPaper(params) {
			console.log('10:25:15 🚀 ~ file: questionList.vue:1030 ~ ', params)
			try {
				let paperData = await addUserPaper(params)

				uni.showToast({
					title: '提交成功',
					icon: 'success',
					success: () => {
						uni.redirectTo({
							url: `/pages/question/score?type=${this.type}&id=${paperData.data.id}&opc=${this.query.opc}`
						})
					}
				})
			} catch (err) {
				console.error('提交理论试卷失败:', err)
				uni.showToast({
					title: '提交失败，请重试',
					icon: 'none'
				})
			}
		},

		/**
		 * 构建科目三试卷参数
		 * @param {Object} score - 得分信息
		 * @param {boolean} isCompleted - 是否完成所有题目
		 * @returns {Object} 试卷参数
		 */
		buildSubPaperParams(score, isCompleted = false) {
			return {
				opc: this.query.opc,
				startTime: this.startTime,
				list: this.list.map(item => {
					return {
						id: item.id,
						questions: item.questions.map(question => {
							return {
								qid: question.id,
								score: isCompleted ? 1 : (question.answer.split(',').sort().join(',') === question.userAnswer.split(',').sort().join(',') ? 1 : ''),
								userAnswer: question.userAnswer,
								answer: question.answer
							}
						})
					}
				})
			}
		},

		/**
		 * 构建理论试卷参数
		 * @param {Object} score - 得分信息
		 * @param {boolean} isCompleted - 是否完成所有题目
		 * @returns {Object} 试卷参数
		 */
		buildUserPaperParams(score, isCompleted = false) {
			return {
				...this.paper,
				updateTime: this.startTime, // 试卷开始时间
				correct: score.correct, // 正确题目数
				wrong: score.wrong, // 错误题目数
				unknown: score.total - score.answered, // 未答题目数
				score: score.correct, // 正确率
				topicList: isCompleted ? this.originalList : this.originalList.map(item => {
					return {
						...item,
						userAnswer: item.userAnswer || (item.questions && item.questions[0] ? item.questions[0].userAnswer : '')
					}
				})
			}
		},

		/**
		 * 统一的答题逻辑
		 * 处理用户答题，更新答案状态，判断正确性，并可能自动跳转到下一题
		 * @param {Object} questionData - 答题数据，包含用户答案和选项信息
		 */
		async handleAnswer(questionData) {
			const currentGlobalIndex = this.currItemNo - 1
			const currentQuestion = this.list[currentGlobalIndex]
			if (!currentQuestion) return

			// 设置答题状态，防止自动跳转
			this.isSubmittingAnswer = true

			try {
				// 确定要更新的子问题索引
				const questionIndex = questionData.questionIndex || 0
				const targetQuestion = currentQuestion.questions[questionIndex]

				if (!targetQuestion) return

			// 更新答案和状态
			targetQuestion.userAnswer = questionData.userAnswer
			targetQuestion.options = questionData.options
			targetQuestion.isSubmitted = true
			currentQuestion.isSubmitted = true

			// 同步更新原始数据中的用户答案
			this.syncUserAnswerToOriginal(currentGlobalIndex, questionIndex, questionData.userAnswer)

				// 判断答案是否正确
				const isCorrect = targetQuestion.answer === questionData.userAnswer

				// 显示答题结果提示
				uni.showToast({
					title: isCorrect ? '答对了' : '答错了',
					icon: 'none'
				})

				// 检查是否需要自动下一题
				const shouldAutoNext = () => {
					if (isCorrect) {
						const currentQuestion = this.list[currentGlobalIndex]
						const allQuestionsAnswered = currentQuestion.questions.every(q => q.isSubmitted)
						const allQuestionsCorrect = currentQuestion.questions.every(q =>
							q.isSubmitted && q.userAnswer === q.answer
						)
						return allQuestionsAnswered && allQuestionsCorrect
					}
					return false
				}
	 console.log(targetQuestion);
	 
				// 每次答题都提交答案到服务器（仅 mode = 1 时）
				if (this.mode == 1) {
					try {
						await addUserTopic({
							id: targetQuestion.id ,
							right: isCorrect,
							answer: questionData.userAnswer
						})
						// 接口成功返回后，检查是否需要自动下一题
						// if (shouldAutoNext()) {
						// 	setTimeout(() => {
						// 		this.nextQuestion() // Auto-advances with 3000ms delay
						// 	}, 200)
						// }
					} catch (err) {
						console.error('提交答案失败:', err)
						// 接口失败时不进行自动下一题
					}
				} else if (this.mode == 2) {
					// mode = 2 时，如果答案全部正确，直接下一题（不提交接口）
					// if (shouldAutoNext()) {
					// 	setTimeout(() => {
					// 		this.nextQuestion() // Auto-advances with 3000ms delay
					// 	}, 200)
					// }
				}
			} finally {
				// 答题完成后，延迟重置状态，避免立即触发自动跳转
				setTimeout(() => {
					this.isSubmittingAnswer = false
				}, 100)
			}
		},

		/**
		 * 同步用户答案到原始数据
		 * @param {number} globalIndex - 全局索引
		 * @param {number} questionIndex - 子题目索引
		 * @param {string} userAnswer - 用户答案
		 */
		syncUserAnswerToOriginal(globalIndex, questionIndex, userAnswer) {
			if (!this.originalList[globalIndex]) return

			const originalItem = this.originalList[globalIndex]

			// 处理不同的数据结构
			if (originalItem.questions && originalItem.questions.length > 0) {
				// 图片+多个问题的结构
				if (originalItem.questions[questionIndex]) {
					originalItem.questions[questionIndex].userAnswer = userAnswer
				}
				// 同时更新顶层的userAnswer（如果有的话）
				if (questionIndex === 0) {
					originalItem.userAnswer = userAnswer
				}
			} else {
				// 单个问题的结构
				originalItem.userAnswer = userAnswer
			}
		},

	/**
	 * 跳转到下一题
	 */
	async nextQuestion() {
		console.log('[nextQuestion] 开始执行, currItemNo:', this.currItemNo, 'total:', this.query.total, 'isSwiperAnimating:', this.isSwiperAnimating)
		
		// ⭐ 防止重复点击：只要有操作在进行中就直接返回
		if (this.isSwiperAnimating) {
			console.log('[nextQuestion] 操作进行中，忽略本次点击')
			return
		}
		
		if (this.currItemNo < this.query.total) {
			const nextQuestionNo = this.currItemNo + 1
			console.log('[nextQuestion] 准备跳转到第', nextQuestionNo, '题')
			
			// 快速检查下一题数据是否已存在
			const nextIndex = nextQuestionNo - 1
			const nextItem = this.list[nextIndex]
			const hasData = nextItem && nextItem !== null && nextItem.questions
			
			if (!hasData) {
				// 数据不存在，立即设置锁，加载数据
				console.log('[nextQuestion] 第', nextQuestionNo, '题数据未加载，开始加载')
				this.isSwiperAnimating = true  // ⭐ 立即上锁
				
				uni.showToast({
					title: '下一题数据加载中，请稍候...',
					icon: 'none',
					duration: 2000
				})
				
				// 加载数据
				const targetPageNum = Math.floor(nextIndex / this.query.pageSize) + 1
				try {
					await this.loadPageData(targetPageNum)
					console.log('[nextQuestion] 数据加载完成')
				} catch (err) {
					console.error('加载下一题数据失败:', err)
				} finally {
					this.isSwiperAnimating = false  // ⭐ 加载完成，释放锁
				}
				return
			}
			
		console.log('[nextQuestion] 执行跳转, current:', this.current, 'next current:', this.current + 1, 'list length:', this.list.length)
		console.log('[nextQuestion] 下一题数据:', this.list[nextQuestionNo - 1])
		
		// 设置标志，表示是程序主动触发的切换，并且开始动画
		this.isProgrammaticSwipe = true
		this.isSwiperAnimating = true  // ⭐ 立即上锁
		
		// 参考swiperTest.vue的实现，传递正确的参数
		changeSwiperItem(this, this.current + 1, this.list, this.duration, () => {
			console.log('[nextQuestion] changeSwiperItem 回调执行, 新的 currItemNo:', this.currItemNo)
			// 保存当前进度
			this.saveProgress(this.currItemNo)
			this.checkLoadMore()
			
			// 重置标志
			this.isProgrammaticSwipe = false
			this.isSwiperAnimating = false  // ⭐ 动画完成，释放锁
		})
		} else {
			// 到达最后一题时，提示用户是否清空做题记录
			this.showClearRecordPrompt()
		}
	},

		/**
		 * 显示清空做题记录提示
		 * 当用户到达最后一题时调用
		 */
		showClearRecordPrompt() {
			// 检查是否已经完成所有题目
			const answeredCount = this.correctCount + this.wrongCount
			
			if (answeredCount === 0) {
				// 如果没有答题，直接提示
				uni.showModal({
					title: '提示',
					content: '您还没有开始答题，是否要清空做题记录重新开始？',
					confirmText: '清空记录',
					cancelText: '继续做题',
					success: (res) => {
						if (res.confirm) {
							this.clearRecord()
						}
					}
				})
				return
			}
			if(this.type == 1 && this.mode == 1){
				// 如果已经答题，显示完成提示和清空选项
				uni.showModal(
				{
						title: '恭喜完成！',
						content: `您已完成所有题目！是否要清空做题记录重新开始？`,
						confirmText: '清空记录',
						cancelText: '查看结果',
						success: (res) => {
							if (res.confirm) {
								// 用户选择清空记录
								this.clearRecord()
							} else {
								// 用户选择查看结果，跳转到成绩页面
								this.submitPaper()
							}
						}
					})
					
				}else{
					this.submitPaper()
				}
				
			},
	/**
	 * 跳转到上一题
	 */
	async prevQuestion() {
		console.log('[prevQuestion] 开始执行, currItemNo:', this.currItemNo, 'isSwiperAnimating:', this.isSwiperAnimating)
		
		// ⭐ 防止重复点击：只要有操作在进行中就直接返回
		if (this.isSwiperAnimating) {
			console.log('[prevQuestion] 操作进行中，忽略本次点击')
			return
		}
		
		if (this.currItemNo > 1) {
			const prevQuestionNo = this.currItemNo - 1
			console.log('[prevQuestion] 准备跳转到第', prevQuestionNo, '题')
			
			// 快速检查上一题数据是否已存在
			const prevIndex = prevQuestionNo - 1
			const prevItem = this.list[prevIndex]
			const hasData = prevItem && prevItem !== null && prevItem.questions
			
			if (!hasData) {
				// 数据不存在，立即设置锁，加载数据
				console.log('[prevQuestion] 第', prevQuestionNo, '题数据未加载，开始加载')
				this.isSwiperAnimating = true  // ⭐ 立即上锁
				
				uni.showToast({
					title: '上一题数据加载中，请稍候...',
					icon: 'none',
					duration: 2000
				})
				
				// 加载数据
				const targetPageNum = Math.floor(prevIndex / this.query.pageSize) + 1
				try {
					await this.loadPageData(targetPageNum)
					console.log('[prevQuestion] 数据加载完成')
				} catch (err) {
					console.error('加载上一题数据失败:', err)
				} finally {
					this.isSwiperAnimating = false  // ⭐ 加载完成，释放锁
				}
				return
			}
			
			console.log('[prevQuestion] 执行跳转')
			
			// 设置标志，表示是程序主动触发的切换，并且开始动画
			this.isProgrammaticSwipe = true
			this.isSwiperAnimating = true  // ⭐ 立即上锁
			
			// 参考swiperTest.vue的实现，传递正确的参数
			changeSwiperItem(this, this.current - 1, this.list, this.duration, () => {
				// 保存当前进度
				this.saveProgress(this.currItemNo)
				
				// 重置标志
				this.isProgrammaticSwipe = false
				this.isSwiperAnimating = false  // ⭐ 动画完成，释放锁
			})
		} else {
			uni.showToast({
				title: '已经是第一题了',
				icon: 'none'
			})
		}
	},

	/**
	 * Swiper切换事件处理
	 * @param {Object} event - 切换事件对象
	 */
	async swiperChange(event) {
		const { current } = event.detail
		console.log('[swiperChange] 开始, event.current:', current, 'this.current:', this.current, 'currItemNo:', this.currItemNo, 'isProgrammaticSwipe:', this.isProgrammaticSwipe)
		
		// 如果是程序主动触发的切换（nextQuestion/prevQuestion），跳过处理，避免重复加载
		if (this.isProgrammaticSwipe) {
			console.log('[swiperChange] 程序主动触发，跳过swiperChange处理')
			return
		}
		
		// 计算目标题目编号（从1开始）
		let targetQuestionNo
		if (current > this.current) {
			// 向后滑动
			targetQuestionNo = this.currItemNo + 1
			console.log('[swiperChange] 向后滑动到第', targetQuestionNo, '题')
		} else if (current < this.current) {
			// 向前滑动
			targetQuestionNo = this.currItemNo - 1
			console.log('[swiperChange] 向前滑动到第', targetQuestionNo, '题')
		} else {
			// 没有变化
			console.log('[swiperChange] current未变化，跳过')
			return
		}
		
		// 检查并加载目标题目数据
		const isReady = await this.checkAndLoadQuestion(targetQuestionNo, '目标题目')
		console.log('[swiperChange] 数据检查结果:', isReady)
		
		if (!isReady) {
			// 数据未加载，阻止滑动
			console.log('[swiperChange] 数据未就绪，阻止滑动')
			return
		}
		
		console.log('[swiperChange] 执行changeSwiperItem, current:', current)
		// 使用防抖机制，避免频繁切换导致的闪烁
		// 使用kevy-enhanced-swiper的计算逻辑，参考swiperTest.vue的实现
		// 注意：这里使用this.list而不是全局list，因为我们的数据结构不同
		changeSwiperItem(this, Number(current), this.list, this.duration, () => {
			console.log('[swiperChange] changeSwiperItem 回调执行, 新的 currItemNo:', this.currItemNo)
			// 切换完成后的回调
			// 保存当前进度
			this.saveProgress(this.currItemNo)
			
			// 检查是否需要加载更多
			this.checkLoadMore()
		})
	},


		/**
		 * 统一题目数据结构转换
		 * 将不同来源的题目数据转换为统一格式，支持单选、多选、判断题
		 * @param {Array} originalData - 原始题目数据
		 * @returns {Array} 转换后的统一格式数据
		 */
		transformData(originalData) {
			return originalData.map(item => {
				// 确定题目类型（1:单选 2:多选 3:判断）
				const questionType = item.type || item.tqType || '1'

				// 清理HTML标签和样式
				const cleanText = (text) => {
					if (!text) return ''
					return text.replace(/<[^>]+>/g, '').replace(/style="[^"]*"/g, '')
				}

			// 过滤掉除img标签外的所有HTML标签
			const removePTags = (text) => {
				if (typeof text !== 'string') return text;
				// 先保存所有img标签
				const imgTags = [];
				const placeholder = '___IMG_PLACEHOLDER___';
				let processedText = text.replace(/<img[^>]*>/gi, (match) => {
					imgTags.push(match);
					return `${placeholder}${imgTags.length - 1}${placeholder}`;
				});
				// 移除所有其他HTML标签
				processedText = processedText.replace(/<[^>]+>/g, '');
				// 还原img标签
				processedText = processedText.replace(/___IMG_PLACEHOLDER___(\d+)___IMG_PLACEHOLDER___/g, (match, index) => {
					return imgTags[parseInt(index)];
				});
				return processedText;
			}
		// const removePTags = (text) => {
        //         if (typeof text !== 'string') return text;
        //         return text.replace(/^<p>/i, '').replace(/<\/p>$/i, '');
        //     }
			
			// 处理选项数据
			const processOptions = (options, answer, userAnswer = '') => {
				if (Array.isArray(options)) {
					// 多选题选项
					return options.map((option, index) => ({
						text: `${String.fromCharCode(65 + index)}、${removePTags(option.text)}`,
						value: option.value,
						checked: userAnswer.includes(option.value),
						answer: answer,
						userAnswer: userAnswer
					}))
				} else if (typeof options === 'string') {
					// 单选题选项字符串：不设置checked属性
					const optionStrings = options.split('~!!~')
					return optionStrings.map((option, index) => ({
						text: `${String.fromCharCode(65 + index)}、${removePTags(option)}`,
						value: String.fromCharCode(65 + index),
						checked: false, // 单选题不设置checked
						answer: answer,
						userAnswer: userAnswer
					}))
				}
				return []
			}

				// 生成判断题选项（对/错）
				const getJudgeOptions = (answer, userAnswer = '') => [
					{
						text: 'A、对',
						value: '对',
						checked: false, // 判断题不设置checked
						answer: answer,
						userAnswer: userAnswer
					},
					{
						text: 'B、错',
						value: '错',
						checked: false, // 判断题不设置checked
						answer: answer,
						userAnswer: userAnswer
					}
				]

				// 构建统一的题目数据结构
				const transformedItem = {
					id: this.type == 6 ? item.topicId : item.id,
					type: questionType,
					img: item.img || '',
					analysis: item.analysis || '',
					collect: this.type == 4 ? true : (item.collect || false),
					isSubmitted: false,
					userAnswer: item.userAnswer || '',
					user: item.user,
					all: item.all,
					questions: []
				}

				// 处理题目内容结构
				if (item.questions && item.questions.length > 0) {
					// 图片+多个子问题的复合结构
					transformedItem.questions = item.questions.map(q => ({
						id: q.id,
						type: questionType, // 添加题目类型
						title: cleanText(q.title),
						answer: q.answer,
						userAnswer: q.userAnswer || '',
						options: processOptions(q.options, q.answer, q.userAnswer),
						analysis: q.analysis || '',
						isSubmitted: q.userAnswer !== undefined && q.userAnswer !== ''
					}))
				} else {
					// 单个问题的简单结构
					const title = cleanText(item.title || item.name)
					const answer = item.answer
					const userAnswer = item.userAnswer || ''

					let options = []
					if (questionType === '3') {
						// 判断题：生成对/错选项
						options = getJudgeOptions(answer, userAnswer)
					} else {
						// 单选题或多选题：处理选项数据
						options = processOptions(item.options, answer, userAnswer)
					}

					transformedItem.questions = [{
						id: this.type == 6 ? item.topicId : item.id,
						type: questionType, // 添加题目类型
						title: title,
						answer: answer,
						userAnswer: userAnswer,
						options: options,
						totalError:item.totalError || item.errorCount,
						totalRight:item.totalRight,
						analysis: item.analysis || '',
						isSubmitted: userAnswer !== undefined && userAnswer !== ''
					}]
				}

				return transformedItem
			})
		},
		/**
		 * 关闭答题卡弹窗
		 */
		closeList() {
			this.$refs.popup.close()
		},
		/**
		 * 选择题目并跳转
		 * 支持跳转到任意题目，直接加载目标页面数据
		 * @param {number} index - 题目索引
		 */
		async selectItem(index) {
			if (index < 0 || index >= Math.round(this.query.total)) {
				return
			}

			// 防止重复点击
			if (this.isJumpLoading) {
				return
			}

			try {
				const targetQuestionNo = index + 1
				const currentQuestionNo = this.currItemNo
				
				// 计算目标题目所在的页码
				const targetPageNum = Math.floor(index / this.query.pageSize) + 1
				const needLoadData = !this.list[index] || !this.list[index]?.questions
				// 判断是否为大距离跳转
				const jumpDistance = Math.abs(targetQuestionNo - currentQuestionNo)
				const isLargeJump = jumpDistance > this.query.pageSize || jumpDistance > 50
				
				// 如果需要加载数据或者是大跳转，显示loading
				if (needLoadData || isLargeJump) {
					this.isJumpLoading = true
					uni.showLoading({
						title: needLoadData ? '正在加载题目...' : '正在跳转题目...',
						mask: true
					})
				}
				
				// 如果目标题目数据未加载，直接加载目标页面
				if (needLoadData) {
					// 直接跳转到目标页面，用空数组补齐前面的数据
					await this.loadTargetPageDirectly(targetPageNum, index)
				}

				// 使用kevy-enhanced-swiper的跳转功能
				leapToItem(this, targetQuestionNo, this.list, this.duration, () => {
					// 保存当前进度
					this.saveProgress(targetQuestionNo)
					
					// 关闭答题卡弹窗
					this.$refs.popup.close()

					// 滚动到当前题目
					this.$nextTick(() => {
						const query = uni.createSelectorQuery().in(this)
						query.select(`.item-box-${index}`).boundingClientRect()
						query.select('.list-item-box').boundingClientRect()
						query.exec(res => {
							if (res[0] && res[1]) {
								const itemRect = res[0]
								const containerRect = res[1]
								const targetScrollTop = itemRect.top - containerRect.top - containerRect.height / 2 + itemRect.height / 2
								this.scrollTop = Math.max(0, targetScrollTop)
							}
						})
					})
				})
			} catch (error) {
				console.error('跳转题目失败:', error)
				uni.showToast({
					title: '跳转失败，请重试',
					icon: 'none'
				})
			} finally {
				// 确保关闭loading
				if (this.isJumpLoading) {
					uni.hideLoading()
					this.isJumpLoading = false
				}
			}
		},
		async submitPaper() {
			try {
						// 如果不是顺序练习或模拟考试,直接返回
				if (this.type != 2 && this.type != 1) {
					return
				}


				// 计算已答题数量（按题目整体计算）
				const correctCount = this.list.reduce((acc, item) => {
					if (!item.questions || !item.questions.length) return acc
					
					// 只有当所有子问题都答对了才算正确
					const allQuestionsAnswered = item.questions.every(question =>
						question.userAnswer !== undefined && question.userAnswer !== ''
					)
					const allQuestionsCorrect = item.questions.every(question =>
						question.userAnswer !== undefined &&
						question.userAnswer !== '' &&
						question.answer === question.userAnswer
					)
					
					return acc + (allQuestionsAnswered && allQuestionsCorrect ? 1 : 0)
				}, 0)

				const wrongCount = this.list.reduce((acc, item) => {
					if (!item.questions || !item.questions.length) return acc
					
					// 如果有任何子问题答错了就算错误
					const hasWrongAnswer = item.questions.some(question =>
						question.userAnswer !== undefined &&
						question.userAnswer !== '' &&
						question.answer !== question.userAnswer
					)
					
					return acc + (hasWrongAnswer ? 1 : 0)
				}, 0)
				
				// 计算已答题总数
				const answeredCount = correctCount + wrongCount
				
				if (this.type != 2 && answeredCount === 0) {
					return
				}
				
				// 算得分
				const score = {
					total: this.query.total, // 总题目数
					answered: answeredCount, // 已答题目数
					correct: correctCount, // 正确题目数
					wrong: wrongCount, // 错误题目数
					accuracy: Math.round((correctCount / answeredCount) * 100) || 0, // 正确率
					endTime: (() => {
						const duration = new Date().getTime() - this.startTime;
						const hours = Math.floor(duration / (1000 * 60 * 60));
						const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60));
						const seconds = Math.floor((duration % (1000 * 60)) / 1000);
						return `${hours}时${minutes}分${seconds}秒`;
					})(),
				}
		
						// 保存得分信息
				uni.setStorageSync('examScore', score)
						let params
				// 跳转到成绩页面 如果是模拟考试走接口其他不走
				if (this.type == 2) {
					// 检查模拟考试最低完成度（20%）
					const minRequiredAnswers = Math.ceil(this.query.total * 0.2)
					if (answeredCount < minRequiredAnswers) {
						const remainingAnswers = minRequiredAnswers - answeredCount
						uni.showModal({
							title: '提示',
							content: `模拟考试至少需要完成${minRequiredAnswers}题（20%）才能提交，您还需要再答${remainingAnswers}题`,
							showCancel: false,
							confirmText: '继续答题',
							success: () => {
								this.topicClick()
							}
						})
						return
					}

					// 检查是否有未完成的题目
					if (answeredCount < this.query.total) {
						const unfinishedCount = this.query.total - answeredCount
						uni.showModal({
							title: '提示',
							content: `还有${unfinishedCount}题未完成，是否继续？`,
							cancelText: '继续做题',
							confirmText: '提交试卷',
							success: (res) => {
								if (res.confirm) {
									if (this.mode == 2) {
										params = this.buildSubPaperParams(score, false)
								
										this.submitSubPaper(params)
									} else {
										params = this.buildUserPaperParams(score, false)
								
										this.submitUserPaper(params)
									}

								} else {
									this.topicClick()
								}
							}
						})
					} else {
						if (this.mode == 2) {
							params = this.buildSubPaperParams(score, true)
					
							this.submitSubPaper(params)
						} else {
							
							params = this.buildUserPaperParams(score, true)
							
							this.submitUserPaper(params)
						}
					}
				} else {
					uni.redirectTo({
						url: `/pages/question/score?type=${this.type}&opc=${this.query.opc}`
					})
				}
			} catch (err) {
				console.error('提交试卷失败:', err)
				uni.showToast({
					title: '提交失败，请重试',
					icon: 'none'
				})
			}
		},

		/**
		 * 切换答题模式
		 * @param {number} val - 模式值：1为答题模式，2为背题模式
		 */
		modeSwitch(val) {
			this.question_mode = val
		},

		/**
		 * 预览图片
		 * @param {string} val - 图片URL
		 */
		previewImage(val) {
			uni.previewImage({
				urls: [val]
			})
		},

		/**
		 * 加载下一页数据
		 * 支持分页加载，根据模式调用不同的API接口
		 */
		async loadNextPage() {
			// 检查是否还有更多数据可加载
			if (this.list.length >= this.query.total && this.query.total > 0) {
				return
			}

			// 防止重复加载
			if (this.isPageLoading) {
				return
			}

			try {
				this.isPageLoading = true
				uni.showLoading({
					title: '加载更多题目...',
					mask: true
				})

				this.query.pageNum++

				// 根据练习模式调用对应的API接口
				let res
				if (this.mode == 2) {
					// 科目三模式：调用科目三相关接口
					res = await getSubPaper({
						opc: this.query.opc,
						pageSize: this.query.pageSize,
						pageNum: this.query.pageNum,
						custom: this.type == 2 ? 10 : 0,
						type: this.type == 1 ? 0 : 1
					})
					const list = res.data.list.map(item => ({
						...item,
						type: item.tqType,
					}))
					const newData = this.transformData(list)
					this.originalList = [...this.originalList, ...list] // 保存原始数据
					this.list = [...this.list, ...newData]
				} else {
					// 理论模式：根据练习类型调用对应接口
					if (this.type == 1) {
						res = await getTopicList({
							pageNum: this.query.pageNum,
							pageSize: this.query.pageSize,
							opc: this.query.opc,
							...(this.topicCode ? { topicCode: this.topicCode } : {})
						})
						const newData = this.transformData(res.data.list)
						this.originalList = [...this.originalList, ...res.data.list] // 保存原始数据
						this.list = [...this.list, ...newData]
					} else if (this.type == 6) {
						res = await getTopicErrorTop({
							pageNum: this.query.pageNum,
							pageSize: this.query.pageSize,
							opc: this.query.opc,
							...(this.topicCode ? { topicCode: this.topicCode } : {})
						})
						const newData = this.transformData(res.data)
						this.originalList = [...this.originalList, ...res.data] // 保存原始数据
						this.list = [...this.list, ...newData]
					}
				}

			} catch (err) {
				console.error('加载下一页失败:', err)
				// 加载失败时恢复页码
				this.query.pageNum--
				uni.showToast({
					title: '加载失败，请重试',
					icon: 'none'
				})
			} finally {
				// 确保关闭loading
				if (this.isPageLoading) {
					uni.hideLoading()
					this.isPageLoading = false
				}
			}
		},
		
	/**
	 * 静默加载下一页数据（不显示loading提示）
	 * 用于在后台预加载，提升用户体验
	 */
	async loadNextPageSilently() {
		// 检查是否还有更多数据可加载
		if (this.list.length >= this.query.total && this.query.total > 0) {
			console.log('已加载所有数据，无需继续加载')
			return
		}

		// 计算下一页的页码
		const nextPageNum = this.query.pageNum + 1
		const totalPages = Math.ceil(this.query.total / this.query.pageSize)
		
		// 检查下一页是否存在
		if (nextPageNum > totalPages) {
			console.log(`下一页（第${nextPageNum}页）超出总页数（${totalPages}页），无需加载`)
			return
		}
		
		// 检查下一页是否已经加载过
		const nextPageStartIndex = (nextPageNum - 1) * this.query.pageSize
		const nextPageEndIndex = Math.min(nextPageNum * this.query.pageSize, this.query.total)
		const hasNextPageData = this.list.slice(nextPageStartIndex, nextPageEndIndex).some(item => item !== null && item !== undefined && item.questions)
		
		if (hasNextPageData) {
			console.log(`下一页（第${nextPageNum}页）已加载，跳过`)
			return
		}

		try {
			console.log(`开始静默加载下一页（第${nextPageNum}页）...`)
			
			// 直接调用 loadPageData，统一使用 loadingPages 防重复机制
			await this.loadPageData(nextPageNum)
			
			// 更新页码
			this.query.pageNum = nextPageNum
			
			console.log(`静默加载第${nextPageNum}页完成`)

		} catch (err) {
			console.error(`静默加载第${nextPageNum}页失败:`, err)
			// 静默失败，不显示错误提示，不影响用户体验
		}
	},
		
		/**
		 * 直接跳转到目标页面，按顺序加载所需页面数据
		 * 如果目标题目在第3页，会先加载第3页，然后加载第2页，最后加载第1页
		 * @param {number} targetPageNum - 目标页码
		 * @param {number} targetIndex - 目标题目索引
		 */
		async loadTargetPageDirectly(targetPageNum, targetIndex) {
			try {
				// 计算目标页面的起始索引
				const targetPageStartIndex = (targetPageNum - 1) * this.query.pageSize
				
				// 确保list数组有足够的空间，用null填充到目标页面起始位置
				while (this.list.length < targetPageStartIndex) {
					this.list.push(null)
				}
				
				// 确保originalList数组也有足够的空间
				while (this.originalList.length < targetPageStartIndex) {
					this.originalList.push(null)
				}
				
		// 只有type == 1（顺序练习）或type == 6（易错题）需要分页加载
		if (this.type == 1 || this.type == 6) {
			// 先加载目标页面
			console.log(`加载目标页面: 第${targetPageNum}页`)
			await this.loadPageData(targetPageNum)
			
			// 延迟后台预加载前后页，等待swiper跳转完成
			setTimeout(() => {
				this.preloadAdjacentPages(targetPageNum).catch(err => {
					console.error('后台预加载前后页失败:', err)
				})
			}, 300) // 延迟300ms，等待swiper跳转动画完成
		} else {
			console.log('当前练习类型不支持分页加载，跳过数据加载')
		}
				
			} catch (error) {
				console.error('直接加载目标页面失败:', error)
				throw error
			}
		},

		/**
		 * 直接加载目标页面并补齐中间空数据
		 * 避免逐页加载，直接跳转到目标页面
		 * @param {number} targetPageNum - 目标页码
		 * @param {number} targetIndex - 目标题目索引
		 */
		async loadTargetPageWithPadding(targetPageNum, targetIndex) {
			try {
				// 确保list数组有足够的空间，用空对象填充到目标位置
				const requiredLength = targetIndex + 1
				while (this.list.length < requiredLength) {
					this.list.push(null)
				}
				
				// 确保originalList数组也有足够的空间
				while (this.originalList.length < requiredLength) {
					this.originalList.push(null)
				}
				
				// 直接加载目标页面数据
				await this.loadPageData(targetPageNum)
				
			} catch (error) {
				console.error('加载目标页面失败:', error)
				throw error
			}
		},
		
		/**
		 * 直接加载指定页码的数据
		 * 智能检测缺失页面，按需加载数据，确保数据连续性
		 * @param {number} targetPageNum - 目标页码
		 */
		async loadSpecificPage(targetPageNum) {
			try {
				// 检测需要加载的缺失页面
				const missingPages = []
				
				// 遍历所有页面，找出数据缺失的页面
				for (let pageNum = 1; pageNum <= targetPageNum; pageNum++) {
					const startIndex = (pageNum - 1) * this.query.pageSize
					const endIndex = pageNum * this.query.pageSize
					
					// 检查当前页面数据是否完整
					const hasData = this.list.slice(startIndex, endIndex).some(item => item !== null && item !== undefined)
					
					if (!hasData) {
						missingPages.push(pageNum)
					}
				}
				
				// 按顺序加载所有缺失的页面数据
				for (const pageNum of missingPages) {
					await this.loadPageData(pageNum)
				}

                

			} catch (err) {
				console.error('加载指定页面失败:', err)
				uni.showToast({
					title: '加载失败',
					icon: 'none'
				})
			}
		},
		
	/**
	 * 加载单个页面数据的辅助方法
	 * @param {number} pageNum - 页码
	 */
	async loadPageData(pageNum) {
		// 检查该页面是否已经加载过，避免重复加载
		const startIndex = (pageNum - 1) * this.query.pageSize
		const endIndex = Math.min(pageNum * this.query.pageSize, this.query.total)
		const hasPageData = this.list.slice(startIndex, endIndex).some(item => item !== null && item !== undefined && item.questions)
		
		if (hasPageData) {
			console.log(`第${pageNum}页已加载，跳过重复加载`)
			return
		}
		
		// 检查该页面是否正在加载中
		if (this.loadingPages.has(pageNum)) {
			console.log(`第${pageNum}页正在加载中，跳过重复请求`)
			// 等待该页面加载完成
			return new Promise((resolve) => {
				const checkInterval = setInterval(() => {
					if (!this.loadingPages.has(pageNum)) {
						clearInterval(checkInterval)
						resolve()
					}
				}, 100) // 每100ms检查一次
			})
		}
		
		// 添加到正在加载的集合中
		this.loadingPages.add(pageNum)
		console.log(`开始加载第${pageNum}页数据...`)
		
		try {
			let res
			if (this.mode == 2) {
					// 科目三模式
					res = await getSubPaper({
						opc: this.query.opc,
						pageSize: this.query.pageSize,
						pageNum: pageNum,
						custom: this.type == 2 ? 10 : 0,
						type: this.type == 1 ? 0 : 1
					})
					const list = res.data.list.map(item => ({
						...item,
						type: item.tqType,
					}))
					const newData = this.transformData(list)
					
					// 计算这个页面数据应该插入的位置
					const startIndex = (pageNum - 1) * this.query.pageSize
					
					// 确保list数组有足够的空间
					while (this.list.length < startIndex + newData.length) {
						this.list.push(null)
					}
					
					// 确保originalList数组有足够的空间
					while (this.originalList.length < startIndex + newData.length) {
						this.originalList.push(null)
					}
					
					// 将新数据插入到正确位置
					for (let i = 0; i < newData.length; i++) {
						this.list[startIndex + i] = newData[i]
					}
					
					// 同时更新原始数据
					for (let i = 0; i < list.length; i++) {
						this.originalList[startIndex + i] = list[i]
					}
				} else {
					// 理论模式
					if (this.type == 1) {
						res = await getTopicList({
							pageNum: pageNum,
							pageSize: this.query.pageSize,
							opc: this.query.opc,
							...(this.topicCode ? { topicCode: this.topicCode } : {})
						})
						const newData = this.transformData(res.data.list)
						
						// 计算这个页面数据应该插入的位置
						const startIndex = (pageNum - 1) * this.query.pageSize
						
						// 确保list数组有足够的空间
						while (this.list.length < startIndex + newData.length) {
							this.list.push(null)
						}
						
						// 确保originalList数组有足够的空间
						while (this.originalList.length < startIndex + newData.length) {
							this.originalList.push(null)
						}
						
						// 将新数据插入到正确位置
						for (let i = 0; i < newData.length; i++) {
							this.list[startIndex + i] = newData[i]
						}
						
						// 同时更新原始数据
						for (let i = 0; i < res.data.list.length; i++) {
							this.originalList[startIndex + i] = res.data.list[i]
						}
					} else if (this.type == 6) {
						res = await getTopicErrorTop({
							pageNum: pageNum,
							pageSize: this.query.pageSize,
							opc: this.query.opc,
							...(this.topicCode ? { topicCode: this.topicCode } : {})
						})
						const newData = this.transformData(res.data)
						
						// 计算这个页面数据应该插入的位置
						const startIndex = (pageNum - 1) * this.query.pageSize
						
						// 确保list数组有足够的空间
						while (this.list.length < startIndex + newData.length) {
							this.list.push(null)
						}
						
						// 确保originalList数组有足够的空间
						while (this.originalList.length < startIndex + newData.length) {
							this.originalList.push(null)
						}
						
						// 将新数据插入到正确位置
						for (let i = 0; i < newData.length; i++) {
							this.list[startIndex + i] = newData[i]
						}
						
						// 同时更新原始数据
						for (let i = 0; i < res.data.length; i++) {
							this.originalList[startIndex + i] = res.data[i]
						}
					}
				}
			
			// 数据加载成功，立即更新swiperList以反映最新数据
			console.log(`第${pageNum}页数据加载成功，更新swiperList`)
			this.updateSwiperListForCurrentItem()
			
		} catch (error) {
			console.error(`加载第${pageNum}页数据失败:`, error)
			throw error // 重新抛出错误，让调用者处理
		} finally {
			// 无论成功还是失败，都要从正在加载的集合中移除该页
			this.loadingPages.delete(pageNum)
			console.log(`第${pageNum}页加载流程结束，已从加载队列中移除`)
		}
	},
	
	/**
	 * 根据当前currItemNo更新swiperList
	 * 在数据加载完成后调用，确保swiper显示最新数据
	 */
	updateSwiperListForCurrentItem() {
		const idx = this.currItemNo - 1
		const max = this.list.length
		
		if (idx < 0 || idx >= max) {
			console.log('currItemNo超出范围，跳过更新')
			return
		}
		
		let newSwiperList, newCurrent
		
		if (max <= 3) {
			// 总数不超过3个，显示全部
			newSwiperList = this.list
			newCurrent = idx
		} else {
			// 总数超过3个，显示当前及前后各一个
			if (idx == 0) {
				// 第一题
				newSwiperList = [this.list[0], this.list[1], this.list[2]]
				newCurrent = 0
			} else if (idx == max - 1) {
				// 最后一题
				newSwiperList = [this.list[idx - 2], this.list[idx - 1], this.list[idx]]
				newCurrent = 2
			} else {
				// 中间的题
				newSwiperList = [this.list[idx - 1], this.list[idx], this.list[idx + 1]]
				newCurrent = 1
			}
		}
		console.log('swiperList更新=======',newSwiperList,newCurrent);
		
		
		// 使用Vue的响应式更新
		this.$nextTick(() => {
			this.swiperList = [...newSwiperList]
			this.current = newCurrent
			console.log('swiperList已刷新:', {
				currItemNo: this.currItemNo,
				current: this.current,
				swiperListLength: this.swiperList.length
			})
		})
	},
        



		/**
		 * 获取题目状态
		 * @param {number} index - 题目索引
		 * @returns {Object} 题目状态对象
		 */
		getQuestionStatus(index) {
			const item = this.list[index]
			// 如果题目未加载或为空，返回空状态
			if (!item || !item.questions || item === null) return {}

			if (this.type === 2) {
				// 模拟考试模式：已答为正确
				return {
					correct: item.questions.every(question => question.userAnswer !== '')
				}
			} else {
				// 练习模式：判断对错
				const hasAnswer = item.questions.some(question => question.userAnswer !== '')
				const allCorrect = item.questions.every(question =>
					question.userAnswer !== '' && question.answer === question.userAnswer
				)
				const hasWrong = item.questions.some(question =>
					question.userAnswer !== '' && question.answer !== question.userAnswer
				)

				return {
					correct: hasAnswer && allCorrect,
					wrong: hasAnswer && hasWrong
				}
			}
		},

		/**
		 * 获取子题目状态
		 * @param {number} index - 题目索引
		 * @param {number} subIndex - 子题目索引
		 * @returns {Object} 子题目状态对象
		 */
		getSubQuestionStatus(index, subIndex) {
			const item = this.list[index]
			// 如果题目未加载或为空，返回空状态
			if (!item || !item.questions || !item.questions[subIndex] || item === null) return {}

			const question = item.questions[subIndex]

			if (this.type === 2) {
				// 模拟考试模式：已答为正确
				return {
					correct: question.userAnswer !== ''
				}
			} else {
				// 练习模式：判断对错
				if (question.userAnswer === '') return {}

				return {
					correct: question.answer === question.userAnswer,
					wrong: question.answer !== question.userAnswer
				}
			}
		},


		/**
		 * 收藏/取消收藏题目
		 */
		collectClick() {
			const currentGlobalIndex = this.currItemNo - 1
			if (this.list[currentGlobalIndex].collect) {
				delPaperCollect({
					id: this.list[currentGlobalIndex].id
				}).then(res => {
					this.list[currentGlobalIndex].collect = false
					uni.showToast({
						title: '取消收藏成功',
						icon: 'none'
					})
				})
			} else {
				paperCollect({
					id: this.list[currentGlobalIndex].id
				}).then(res => {
					this.list[currentGlobalIndex].collect = true
					uni.showToast({
						title: '收藏成功',
						icon: 'none'
					})
				})
			}
		},



		/**
		 * 开始倒计时
		 */
		startCountdown() {
			// 计算总秒数
			let totalSeconds = this.countdown.hours * 3600 +
				this.countdown.minutes * 60 +
				this.countdown.seconds;

			this.countdown.timer = setInterval(() => {
				if (totalSeconds <= 0) {
					clearInterval(this.countdown.timer);
					this.submitPaper();
					return;
				}

				totalSeconds--;

				// 更新时分秒
				this.countdown.hours = Math.floor(totalSeconds / 3600);
				this.countdown.minutes = Math.floor((totalSeconds % 3600) / 60);
				this.countdown.seconds = totalSeconds % 60;

				// 更新标题显示倒计时
				if (this.type == '2') {
					this.title = this.formatCountdown();

					// 剩余30分钟时改变标题颜色
					if (this.countdown.hours === 0 && this.countdown.minutes <= 30) {
						uni.setNavigationBarColor({
							frontColor: '#ffffff',
							backgroundColor: '#E23321'
						});
					}
				}
			}, 1000);
		},

		/**
		 * 清除答题记录
		 */
		clearRecord() {
			if(this.type == 3){
				return uni.showModal({
				title: '提示',
				content: '清除答题记录,重新开始',
				success: res => {
					if (res.confirm) {
						delTopicAnswer({
							opc: this.query.opc
						}).then(res => {
							uni.showToast({
								title: '清除成功',
								icon: 'none'
							})
							this.resetToFirstPage()
						})
					}
				}
			})
			}
			uni.showModal({
				title: '提示',
				content: '清除答题记录,重新开始',
				success: res => {
					if (res.confirm) {
						clearTopicAnswer({
							opc: this.query.opc
						}).then(res => {
							uni.showToast({
								title: '清除成功',
								icon: 'none'
							})
							this.resetToFirstPage()
						})
					}
				}
			})
		},

		/**
		 * 重置到第一页第一题
		 * 清空记录后调用，确保题目回到起始位置
		 */
		resetToFirstPage() {
			// 设置重置标志
			this.isResetting = true
			
			// 重置开始时间
			this.startTime = new Date().getTime()
			
			// 重置页码到第一页
			this.query.pageNum = 1
			
			// 清空所有数据
			this.list = []
			this.originalList = []
			this.swiperList = []
			
			// 重置当前题目到第一题
			this.currItemNo = 1
			this.current = 0
			
			// 清除进度记录
			this.clearProgress()
			
			// 重置防抖定时器
			if (this.loadMoreDebounceTimer) {
				clearTimeout(this.loadMoreDebounceTimer)
				this.loadMoreDebounceTimer = null
			}
			
			// 关闭答题卡弹窗（如果打开的话）
			if (this.$refs.popup) {
				this.$refs.popup.close()
			}
			
			// 显示重置提示
			uni.showLoading({
				title: '正在重置题目...',
				mask: true
			})
			
			// 重新加载数据
			this.loadData()
		},
		/**
		 * 点击答题卡，打开弹窗并计算滚动位置
		 */
		topicClick() {
			this.$refs.popup.open()
			if (this.type == 2) {
				return
			}
			// 等待弹窗完全打开后再计算位置
			setTimeout(() => {
				const query = uni.createSelectorQuery().in(this)

				// 获取答题卡容器信息
				query.select('.list-item-box').boundingClientRect()
				// 获取当前题目元素信息
				query.select(`.item-box-${this.currItemNo - 1}`).boundingClientRect()

				query.exec(res => {
					if (!res[0] || !res[1]) return

					const containerRect = res[0]
					const itemRect = res[1]

					// 计算滚动位置
					const containerHeight = containerRect.height
					const itemHeight = itemRect.height
					const itemTop = itemRect.top - containerRect.top

					// 计算目标滚动位置(让当前题目居中)
					const targetScrollTop = itemTop - (containerHeight / 2) + (itemHeight / 2)
					// 设置滚动位置
					this.scrollTop = targetScrollTop > 0 ? targetScrollTop : 0
				})
			}, 100)
		},

		/**
		 * 格式化倒计时显示
		 * @returns {string} 格式化的时间字符串
		 */
		formatCountdown() {
			const { hours, minutes, seconds } = this.countdown;
			return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
		},
	},
onUnload() {
    if (this.countdown.timer) {
        clearInterval(this.countdown.timer);
        this.countdown.timer = null;
    }
    
    // 清理防抖定时器
    if (this.loadMoreDebounceTimer) {
        clearTimeout(this.loadMoreDebounceTimer);
        this.loadMoreDebounceTimer = null;
    }
    
    // 重置重置标志
    this.isResetting = false;
},
	
	/**
	 * 数据监听器
	 */
	watch: {
		/**
		 * 监听当前题目变化
		 * @param {number} newIndex - 新的题目索引
		 */
		currItemNo(newIndex) {
			this.checkLoadMore()
		}
	}
}
</script>

<style lang="scss">
.topic-box {
	.topic-nav {
		display: flex;
		justify-content: center;
		border-radius: 31rpx;
		border: 3px solid #343434;
		height: 64rpx;
		line-height: 64rpx;
		font-weight: 400;
		font-size: 28rpx;
		color: #161616;
		overflow: hidden;

		text {
			width: 170rpx;
			text-align: center;

		}

		.on {
			background-color: #343434;
			color: #fff;
			
		}
	}

	.topic-main {
		color: #1E1E20;
	}
}

.swiper-topic {

	margin-bottom: 220rpx;
}

/* #ifdef WEB */

.uni-swiper-wrapper {
	overflow: visible !important;
}

/* #endif */



.swiper-item {
	width: 100vw !important;
	height: auto !important;
}

.btn {
	width: 150rpx;
	height: 70rpx;
	line-height: 70rpx;
	position: fixed;
	bottom: 150rpx;
	background: #F9F9F9;
	text-align: center;
	border-radius: 10rpx;
	box-shadow: 0px 0px 10rpx 2rpx rgba(0, 0, 0, 0.25);
}

.btn-on {
	background-color: #36a9fb;
	color: #fff;
}

.btn-submit {
	position: fixed;
	bottom: 150rpx;
	left: 50%;
	transform: translate(-50%, 0);
	width: 250rpx;
	height: 70rpx;
	line-height: 70rpx;
	text-align: center;
	color: #36a9fb;
	background: #F9F9F9;
	box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 0.25);
	border-radius: 40rpx;
	font-size: 28rpx;

	.iconfont {
		font-weight: bold;
		font-size: 28rpx;
	}
}

.bottom-box {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
	display: flex;
	justify-content: space-between;
	border-top: 2rpx solid #EBEBEB;
	padding: 25rpx 0;
	background-color: #fff;

	.count {
		font-size: 28rpx;
	}

	.bottom-box-left {
		display: flex;
		align-items: center;
		padding-left: 35rpx;
	}

	.on {
		color: #FEAD04 !important;
	}

	.bottom-box-right {
		display: flex;
		align-items: center;
		padding-right: 35rpx;
		font-weight: 400;
		font-size: 26rpx;
		color: #616161;

		.icon-hanhan-01-01 {
			font-size: 42rpx;
		}
	}

	.bottom-box-tag {
		display: flex;
		justify-content: center;
		align-items: center;
		font-weight: 400;
		font-size: 26rpx;
		color: #000000;
		margin-right: 20rpx;

		.icon-zhengque {
			color: #2386FF;
		}

		.icon-cuowu {
			color: #E23321;
		}

		.iconfont {
			padding-right: 10rpx;
		}
	}
}





.list-topic {
	padding: 30rpx;
	.list-top {
		display: flex;
		justify-content: space-between;

		.list-top-txt {
			font-size: 32rpx;

			.list-top-txt-title {
				font-weight: 600;
				font-size: 34rpx;
				color: #1E1E20;
				display: inline-block;
				margin-right: 20rpx;
			}
		}

		.iconfont {
			font-size: 50rpx;
			font-weight: 700;
		}
	}
}

.list-record {
	display: flex;
	justify-content: space-between;
	height: 75rpx;
	background: #F3F3F3;
	border-radius: 10rpx;
	margin: 30rpx 0;

	.iconfont {
		font-size: 36rpx;
		margin: 0 10rpx;
	}

	.list-record-icon {
		display: flex;
		align-items: center;
		margin-left: 20rpx;

		text {
			font-weight: 400;
			font-size: 26rpx;
			color: #646464;
		}
	}

	.list-record-clear {
		height: 75rpx;
		background: #2386FF;
		border-radius: 10rpx;
		color: #fff;
		text-align: center;
		line-height: 75rpx;
		font-weight: 400;
		font-size: 26rpx;
		padding: 0 20rpx;
	}
}

.list-item-box {
	scroll-behavior: smooth;
	overflow-y: auto;
	max-height: 800rpx;
	padding: 10rpx;

	&::-webkit-scrollbar {
		width: 6rpx;
		background: transparent;
	}

	&::-webkit-scrollbar-thumb {
		background: #ddd;
		border-radius: 3rpx;
	}
}

.list-item {
	display: grid;
	grid-template-columns: repeat(8, 1fr);
	grid-column-gap: 6rpx;

	.list-item-top {
		font-size: 28rpx;
		color: #616161;
		font-weight: 400;
		width: 100%;
		background: #F8F8F8;
		border-radius: 10rpx;
		text-align: center;
		height: 68rpx;
		margin-bottom: 8rpx;
		position: relative;
		transition: all 0.3s;
		display: flex;
		justify-content: center;
		align-items: center;

		.list-item-box-title {
			width: 100%;
			height: 100%;
			display: flex;
			justify-content: center;
			align-items: center;

			&.wrong {
				background: #E23321;
				color: #fff !important;
				box-shadow: 0 2px 8px rgba(226, 51, 33, 0.2);
			}

			&.correct {
				background: #2386FF;
				color: #fff !important;
			}
		}

		&.current {
			border: 2px solid #2386FF;
			transform: scale(1.05);
			z-index: 1;
			box-shadow: 0 2px 8px rgba(35, 134, 255, 0.2);
		}

		&.placeholder {
			background: #F0F0F0;
			opacity: 0.6;
			cursor: default;
			
			.list-item-box-title {
				color: #CCCCCC !important;
			}
		}

	}

}

.multi {
	flex-direction: column;

	.list-item-box-title {
		border-bottom: 2rpx solid #fff;
	}

	.list-item-box-title {
		color: #1E1E20;
		width: 100%;
		display: block;
		text-align: center;

		&.wrong {
			color: #fff !important;
			background: #E23321;
			box-shadow: 0 2px 8px rgba(226, 51, 33, 0.2);

		}

		&.correct {
			color: #fff !important;
			background: #2386FF;
			box-shadow: 0 2px 8px rgba(226, 51, 33, 0.2);
		}
	}

	.list-item-box-item {
		display: grid;
		grid-template-columns: repeat(2, 1fr);
		grid-column-gap: 2rpx;
		width: 100%;
		text-align: center;
	}

	.list-item-box-item-text {
		color: #1E1E20;

		&.correct {
			background: #2386FF;
			border: 2px solid #2386FF;
			transform: scale(1.05);
			z-index: 1;
			box-shadow: 0 2px 8px rgba(35, 134, 255, 0.2);
			color: #fff !important;
		}

		&.wrong {
			background: #E23321;
			box-shadow: 0 2px 8px rgba(226, 51, 33, 0.2);
			color: #fff !important;

		}

		&:last-child {
			border-left: 2rpx solid #fff;
		}
	}
}


</style>